package mutsumimod;

import basemod.AutoAdd;
import basemod.BaseMod;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.GdxRuntimeException;
import com.google.gson.Gson;
import com.megacrit.cardcrawl.localization.*;
import com.megacrit.cardcrawl.unlock.UnlockTracker;
import mutsumimod.cards.BaseCard;
import mutsumimod.character.Mutsumi;
import mutsumimod.monitors.*;
import mutsumimod.relics.BaseRelic;
import mutsumimod.util.CardUtils;
import mutsumimod.util.KeywordInfo;
import mutsumimod.util.varibles.MagicNumberTwoVariable;
import org.clapper.util.classutil.ClassFilter;
import org.clapper.util.classutil.ClassFinder;
import org.clapper.util.classutil.ClassInfo;

import java.nio.charset.StandardCharsets;

import static mutsumimod.MutsumiMod.*;

public class MutsumiCore {

    public static void initialize(){
        Mutsumi.Meta.registerColor();
        receiveMonitor();
    }

    public static void receiveMonitor(){
        BaseMod.subscribe(new CopyMonitor());
        BaseMod.subscribe(new PathDependencyMonitor());
        BaseMod.subscribe(new CardUtils());
        BaseMod.subscribe(new SuperMetalMonitor());
        BaseMod.subscribe(new SakiMoveMonitor());
        BaseMod.subscribe(new ForgetMonitor());
        BaseMod.subscribe(new SakiDownMonitor());
        BaseMod.subscribe(new PantheonizedHeroMonitor());
        BaseMod.subscribe(new EatMonitor());
        BaseMod.subscribe(new ReloadFixMonitor());
        BaseMod.subscribe(new BrokenMonitor());
    }

    public static void receivePostInitialize(){

    }

    public static void receiveEditRelics(){
        new AutoAdd(modID) //Loads files from this mod
                .packageFilter(BaseRelic.class) //In the same package as this class
                .any(BaseRelic.class, (info, relic) -> { //Run this code for any classes that extend this class
                    if (relic.pool != null)
                        BaseMod.addRelicToCustomPool(relic, relic.pool); //Register a custom character specific relic
                    else
                        BaseMod.addRelic(relic, relic.relicType); //Register a shared or base game character specific relic

                    //If the class is annotated with @AutoAdd.Seen, it will be marked as seen, making it visible in the relic library.
                    //If you want all your relics to be visible by default, just remove this if statement.
                    if (info.seen)
                        UnlockTracker.markRelicAsSeen(relic.relicId);
                });

    }

    public static void receiveEditStrings(){
        loadLocalization(defaultLanguage); //no exception catching for default localization; you better have at least one that works.
        if (!defaultLanguage.equals(getLangString())) {
            try {
                loadLocalization(getLangString());
            }
            catch (GdxRuntimeException e) {
                e.printStackTrace();
            }
        }
    }

    public static void loadLocalization(String lang) {
        //While this does load every type of localization, most of these files are just outlines so that you can see how they're formatted.
        //Feel free to comment out/delete any that you don't end up using.
        BaseMod.loadCustomStringsFile(CardStrings.class,
                localizationPath(lang, "CardStrings.json"));
        BaseMod.loadCustomStringsFile(CharacterStrings.class,
                localizationPath(lang, "CharacterStrings.json"));
        BaseMod.loadCustomStringsFile(EventStrings.class,
                localizationPath(lang, "EventStrings.json"));
        BaseMod.loadCustomStringsFile(OrbStrings.class,
                localizationPath(lang, "OrbStrings.json"));
        BaseMod.loadCustomStringsFile(PotionStrings.class,
                localizationPath(lang, "PotionStrings.json"));
        BaseMod.loadCustomStringsFile(PowerStrings.class,
                localizationPath(lang, "PowerStrings.json"));
        BaseMod.loadCustomStringsFile(RelicStrings.class,
                localizationPath(lang, "RelicStrings.json"));
        BaseMod.loadCustomStringsFile(UIStrings.class,
                localizationPath(lang, "UIStrings.json"));
        BaseMod.loadCustomStringsFile(MonsterStrings.class,
                localizationPath(lang, "MonsterStrings.json"));
    }

    public static String localizationPath(String lang, String file) {
        return resourcesFolder + "/localization/" + lang + "/" + file;
    }

    public static void receiveEditKeywords(){
        Gson gson = new Gson();
        String json = Gdx.files.internal(localizationPath(defaultLanguage, "Keywords.json")).readString(String.valueOf(StandardCharsets.UTF_8));
        KeywordInfo[] keywords = gson.fromJson(json, KeywordInfo[].class);
        for (KeywordInfo keyword : keywords) {
            keyword.prep();
            registerKeyword(keyword);
        }

        if (!defaultLanguage.equals(getLangString())) {
            try
            {
                json = Gdx.files.internal(localizationPath(getLangString(), "Keywords.json")).readString(String.valueOf(StandardCharsets.UTF_8));
                keywords = gson.fromJson(json, KeywordInfo[].class);
                for (KeywordInfo keyword : keywords) {
                    keyword.prep();
                    registerKeyword(keyword);
                }
            }
            catch (Exception e)
            {
                logger.warn(modID + " does not support " + getLangString() + " keywords.");
            }
        }
    }

    public static void receiveEditCharacters(){
        Mutsumi.Meta.registerCharacter();
    }

    public static void receiveEditCards(){
        new AutoAdd(modID) //Loads files from this mod
                .packageFilter(BaseCard.class) //In the same package as this class
                .filter(new ClassFilter() {
                    @Override
                    public boolean accept(ClassInfo classInfo, ClassFinder classFinder) {
                        String className = classInfo.getClassName();
                        return !className.contains("deprecated");
                    }
                })
                .setDefaultSeen(true) //And marks them as seen in the compendium
                .cards(); //Adds the cards

        receiveDynamicVariables();
    }

    public static void receiveDynamicVariables(){
        BaseMod.addDynamicVariable(new MagicNumberTwoVariable());
    }
}

